package com.download.net;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

import android.R.integer;
import android.util.Log;

import com.download.cache.AbstractFileCache;
import com.download.util.SysHelper;

public class Downloader {
	
	private static Downloader loader = null;
	private BlockingQueue<DTask> tasks = new LinkedBlockingQueue<DTask>();
	private ExecutorService service = Executors.newFixedThreadPool(SysHelper.getNumCores()-1);
	private AbstractFileCache fileCache;
	
	public static Downloader getInstance(){
		if (loader == null) {
			loader = new Downloader();
		}
		return loader;
	}
	
	// sync和async都是通过DTask.callback回调，
	// sync是主线程回调，而async是非主线程回调
	public boolean downloadFile(DTask task, Boolean isLoadFromFile, Boolean bSync){
		if (bSync) {
			service.submit(new TaskConsumer(task, isLoadFromFile));			
		}else{
			(new TaskConsumer(task, isLoadFromFile)).run();
		}
		
		return true;
	}
	
	private class TaskConsumer implements Runnable{
		private DTask task;
		private Boolean isLoadFromFile;
		
		TaskConsumer(DTask task, Boolean isLoadFromFile){
			this.task = task;
			this.isLoadFromFile = isLoadFromFile;
		}

		@Override
		public void run() {
			File file = getFile(task.url, isLoadFromFile);
			DCallback cb = task.callback;
			if (cb != null) {
				if (file != null && file.exists()) {
					cb.finish(task, true, file);
				}
				else {
					cb.finish(task, false, null);
				}
			}
			else{
				Log.e("", "DwCallback is null...");
			}
			
		}
		
	}
	
	private File getFile(String url, Boolean isLoadFromFile) {
		File f = fileCache.getFile(url);
		
		// 如果有缓存，直接取缓存文件
		if ( isLoadFromFile && f != null && f.exists()){
			return f;
		}

		// 无缓存，下载文件
		try {
			URL imageUrl = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) imageUrl
					.openConnection();
			conn.setConnectTimeout(30000);
			conn.setReadTimeout(30000);
			conn.setInstanceFollowRedirects(true);
			InputStream is = conn.getInputStream();
			OutputStream os = new FileOutputStream(f);
			CopyStream(is, os);
			os.close();
			return f;
		} catch (Exception ex) {
			Log.e("", "Http Exception...\nmessage = " + ex.getMessage());
			return null;
		}
	}
	
	public static void CopyStream(InputStream is, OutputStream os) {
		final int buffer_size = 1024;
		try {
			byte[] bytes = new byte[buffer_size];
			for (;;) {
				int count = is.read(bytes, 0, buffer_size);
				if (count == -1)
					break;
				os.write(bytes, 0, count);
			}
		} catch (Exception ex) {
			Log.e("", "CopyStream catch Exception...");
		}
	}
	
}
